﻿using System;
using System.ComponentModel;
using System.IO.Ports;
using System.Text;
using System.Threading;
using System.Windows;
using WPFExcelReport.Helpers;
using ReflectionStudio.Core.Events;
namespace WPFExcelReport
{
    public partial class TZLCOM
    {
        #region ==DevTyp===========
        public static readonly DependencyProperty DevTypProperty = DependencyProperty.Register("DevTyp",
            typeof(string), typeof(TZLCOM),
            new FrameworkPropertyMetadata("", FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnDevTypChanged));
        public string DevTyp
        {
            get
            {
                return (string)GetValue(DevTypProperty);
            }
            set
            {
                SetValue(DevTypProperty, value);
            }
        }
        private static void OnDevTypChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            var src = sender as TZLCOM;
            if (src != null)
            {
                src.DevTyp = (string)e.NewValue;
                src.TMV.DevTyp = (string)e.NewValue;
            }
        }
        public virtual void OnDevTypChg(string value)
        { }
        #endregion
        #region ==VU0===========
        public static readonly DependencyProperty VU0Property = DependencyProperty.Register("VU0",
            typeof(string), typeof(TZLCOM),
            new FrameworkPropertyMetadata("", FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnVU0Changed));
        public string VU0
        {
            get
            {
                return (string)GetValue(VU0Property);
            }
            set
            {
                SetValue(VU0Property, value);
            }
        }
        private static void OnVU0Changed(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            var src = sender as TZLCOM;
            if (src != null)
            {
                src.VU0 = (string)e.NewValue;
            }
        }
        public virtual void OnVU0Chg(string value)
        { }
        #endregion
        #region ==COMn===========
        public static readonly DependencyProperty COMnProperty = DependencyProperty.Register("COMn",
            typeof(string), typeof(TZLCOM),
            new FrameworkPropertyMetadata("", FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnCOMnChanged));
        public string COMn
        {
            get
            {
                return (string)GetValue(COMnProperty);
            }
            set
            {
                SetValue(COMnProperty, value);
            }
        }
        private static void OnCOMnChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            var src = sender as TZLCOM;
            if (src != null)
            {
                src.COMn = (string)e.NewValue;
                src.TMV.COMn = (string)e.NewValue;
            }
        }
        #endregion 

        #region ==CBaudRate===========
        public static readonly DependencyProperty CBaudRateProperty = DependencyProperty.Register("CBaudRate",
                typeof(int), typeof(TZLCOM),
                new FrameworkPropertyMetadata(9600, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnCBaudRateChanged));
        public int CBaudRate
        {
            get
            {
                return (int)GetValue(CBaudRateProperty);
            }
            set
            {
                SetValue(CBaudRateProperty, value);
            }
        }
        private static void OnCBaudRateChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            var src = sender as TZLCOM;
            if (src != null)
            {
                src.CBaudRate = (int)e.NewValue;
                src.TMV.CBaudRate = (int)e.NewValue;
            }
        }
        #endregion
        /*
        /// <summary>
        ///     //
        // Summary:
        //     No stop bits are used. This value is not supported by the System.IO.Ports.SerialPort.StopBits
        //     property.
       /// None = 0,
        //
        // Summary:
        //     One stop bit is used.
      ///  One = 1,
        //
        // Summary:
        //     Two stop bits are used.
     ///   Two = 2,
        //
        // Summary:
        //     1.5 stop bits are used.
       /// OnePointFive = 3
        /// </summary>
       */
        #region ==CStopBits===========
        public static readonly DependencyProperty CStopBitsProperty = DependencyProperty.Register("CStopBits",
                typeof(int), typeof(TZLCOM),
                new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnCStopBitsChanged));
        public int CStopBits
        {
            get
            {
                return (int)GetValue(CStopBitsProperty);
            }
            set
            {
                SetValue(CStopBitsProperty, value);
            }
        }
        private static void OnCStopBitsChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            var src = sender as TZLCOM;
            if (src != null)
            {
                src.CStopBits = (int)e.NewValue;
                src.TMV.CStopBits = (int)e.NewValue;
            }
        }
        #endregion

        #region ==IsSimulate===========
        public static readonly DependencyProperty IsSimulateProperty = DependencyProperty.Register("IsSimulate",
        typeof(bool), typeof(TZLCOM),
        new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnIsSimulateChanged));
        public bool IsSimulate
        {
            get
            {
                return (bool)GetValue(IsSimulateProperty);
            }
            set
            {
                SetValue(IsSimulateProperty, value);

            }
        }
        private static void OnIsSimulateChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            var src = sender as TZLCOM;
            if (src != null)
            {
                src.IsSimulate = (bool)e.NewValue;
                src.OnSimulateChg((bool)e.NewValue);
            }
        }
        public virtual void OnSimulateChg(bool value)
        {
            TMV.IsSimulate = value;
        }
        #endregion
        #region ==CDataBits===========
        public static readonly DependencyProperty CDataBitsProperty = DependencyProperty.Register("CDataBits",
                typeof(int), typeof(TZLCOM),
                new FrameworkPropertyMetadata(9600, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnCDataBitsChanged));
        public int CDataBits
        {
            get
            {
                return (int)GetValue(CDataBitsProperty);
            }
            set
            {
                SetValue(CDataBitsProperty, value);

            }
        }
        private static void OnCDataBitsChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            var src = sender as TZLCOM;
            if (src != null)
            {
                src.CDataBits = (int)e.NewValue;
                src.TMV.CDataBits = (int)e.NewValue;
            }
        }
        #endregion

        #region ==CParity
        /*===========
        //
        // Summary:
        //     No CParity check occurs.
        None = 0,
        //
        // Summary:
        //     Sets the CParity bit so that the count of bits set is an odd number.
        Odd = 1,
        //
        // Summary:
        //     Sets the CParity bit so that the count of bits set is an even number.
        Even = 2,
        //
        // Summary:
        //     Leaves the CParity bit set to 1.
        Mark = 3,
        //
        // Summary:
        //     Leaves the CParity bit set to 0.
        Space = 4*/
        public static readonly DependencyProperty CParityProperty = DependencyProperty.Register("CParity",
                typeof(int), typeof(TZLCOM),
                new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnCParityChanged));
        public int CParity
        {
            get
            {
                return (int)GetValue(CParityProperty);
            }
            set
            {
                SetValue(CParityProperty, value);

            }
        }
        private static void OnCParityChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            var src = sender as TZLCOM;
            if (src != null)
            {
                src.CParity = (int)e.NewValue;
                src.TMV.CParity = (int)e.NewValue;
            }
        }
        #endregion

        public TZLCOM()
        {
            if (DesignerProperties.GetIsInDesignMode(this))
                return;
            MV = new VICC_ZLAN();
            this.DataContext = MV;
            MV.OnMessage += MV_OnMessage;
            InitializeComponent();
        }

        private void MV_OnMessage(object sender, MessageEventArgs e)
        {
            this.Dispatcher.Invoke(new SetFunctionDelegate(SetFunction), e.Info.Details);
        }
        public delegate void SetFunctionDelegate(string vu);
        public override void Window_Loaded(object sender, RoutedEventArgs e)
        {
            if (DesignerProperties.GetIsInDesignMode(this))
                return;
            if (IsLoaded)
                return;
            TMV.CBaudRate = CBaudRate;
            TMV.CDataBits = CDataBits;
            TMV.CStopBits = CStopBits;
            TMV.COMn = COMn;
            base.Window_Loaded(sender, e);
        }
        protected void SetFunction(string vu)
        {
            VU0 = vu;
        }
        public override void OnMachineReadyChg(bool value)
        {
            if (!value)
                return;
            TMV.Start();
        }

    }
    public partial class VICC_ZLAN
    {
        private bool _IsSimulate = false;
        public bool IsSimulate
        {
            get
            {
                return _IsSimulate;
            }
            set
            {
                _IsSimulate = value;
                OnPropertyChanged("IsSimulate", value);
            }
        }
        private string _DevTyp = "";
        public string DevTyp
        {
            get
            {
                return _DevTyp;
            }
            set
            {
                _DevTyp = value;
                OnPropertyChanged("DevTyp", value);
            }
        }
        private string _VU = "";
        public string VU
        {
            get
            {
                return _VU;
            }
            set
            {
                _VU = value;
                OnPropertyChanged("VU", value);
            }
        }
        private int _CParity = 0;
        public int CParity
        {
            get
            {
                return _CParity;
            }
            set
            {
                _CParity = value;
                OnPropertyChanged("CParity", value);
            }
        }
        private int _CStopBits = 0;
        public int CStopBits
        {
            get
            {
                return _CStopBits;
            }
            set
            {
                _CStopBits = value;
                OnPropertyChanged("CStopBits", value);
            }
        }
        private int _CDataBits = 0;
        public int CDataBits
        {
            get
            {
                return _CDataBits;
            }
            set
            {
                _CDataBits = value;
                OnPropertyChanged("CDataBits", value);
            }
        }
        private string _COMn = "";
        public string COMn
        {
            get
            {
                return _COMn;
            }
            set
            {
                _COMn = value;
                OnPropertyChanged("COMn", value);
            }
        }


        private int _CBaudRate = 0;
        public int CBaudRate
        {
            get
            {
                return _CBaudRate;
            }
            set
            {
                _CBaudRate = value;
                OnPropertyChanged("CBaudRate", value);
            }
        }

        SerialPort _com;
        SerialPort com
        {
            get
            {
                if (_com == null)
                {


                    Parity parity = Parity.None;
                    switch (CParity)
                    {
                        case 0:
                            parity = Parity.None;
                            break;
                        case 1:
                            parity = Parity.Odd;
                            break;
                        case 2:
                            parity = Parity.Even;
                            break;
                        case 3:
                            parity = Parity.Mark;
                            break;
                        case 4:
                            parity = Parity.Space;
                            break;
                    }
                    StopBits stopbits = StopBits.None;
                    switch (CStopBits)
                    {
                        case 0:
                            stopbits = StopBits.None;
                            break;
                        case 1:
                            stopbits = StopBits.One;
                            break;
                        case 15:
                            stopbits = StopBits.OnePointFive;
                            break;
                        case 2:
                            stopbits = StopBits.Two;
                            break;
                    }
                    try
                    {
                        _com = new SerialPort(COMn, CBaudRate, parity, CDataBits, stopbits);
                        if (_com.IsOpen)
                        {
                            _com.Close();
                        }
                        _com.Open();
                        Helpers.LogHelper.info("connectted");
                        //MessageBox.Show("connected");
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("error");
                        Helpers.LogHelper.error(ex.StackTrace + ex.Message);
                    }
                }

                return _com;
            }
        }
        private int _bytesRead;

        string date = "", time = "";
        long ticks;
        Byte[] ReceivedData;
        public void Send()
        {
            //55 AA 02 00 00 01

            byte[] data = new byte[6];

            //开始标记符
            data[0] = 0x55;
            data[1] = 0xAA;
            data[2] = 0x02;
            data[3] = 0x00;

            data[4] = 0x00;
            data[5] = 0x01;
            //MessageBox.Show("sending");
            //Helpers.LogHelper.info("sending");
            com.Write(data, 0, data.Length);
            com.Close();
            MessageBox.Show("sent");
            //Helpers.LogHelper.info("sent");

        }
        private void Com_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            System.Threading.Thread.Sleep(100);//延时100ms 等待接收完数据
                                               //this.Invoke 就是跨线程访问ui 的方法，也是本文的范例 
            ReceivedData = new Byte[com.BytesToRead]; //创建接收字节数组
            com.Read(ReceivedData, 0, ReceivedData.Length); //读取所接收到的数据
            LogHelper.info(ReceivedData.Length + " received");
            if (ReceivedData.Length > 0)
            {
                Helper.GetTime(ref date, ref time, ref ticks);
                switch (DevTyp)
                {
                    case "YHA12":
                        ProcessData(GetYHMsg);
                        break;
                    case "HT1300":
                        ProcessData(GetHTMsg);
                        break;
                    case "CCS280":
                    case "CC5D99RS":
                        ProcessData(GetCDMsg);
                        break;
                    case "XM05B3":
                        ProcessData(GetXM05B3Msg);
                        break;
                    case "XK31":
                        ProcessData(GetXK31Msg);
                        break;
                }
            }
            com.DiscardInBuffer();//丢弃接收缓冲区数据  
        }
        private void ProcessData(Action<string, byte[], int> recvDataAction)
        {
            if (ReceivedData.Length > 0 && recvDataAction != null)
            {
                recvDataAction(ToString(), ReceivedData, ReceivedData.Length);
            }
        }
        bool IsRun = false;
        private Thread thBackgroundWoker = null;
        public void Start()
        {
            //MessageBox.Show("start");
            if (IsRun)
                return;

            if (thBackgroundWoker != null && thBackgroundWoker.IsAlive)
            {
                thBackgroundWoker.Abort();
            }

            thBackgroundWoker = new Thread(new ThreadStart(ReadWork));
            thBackgroundWoker.IsBackground = true;
            isContinue = true;
            thBackgroundWoker.Start();
            IsRun = true;
        }

        private bool isContinue = true;
        int simuvalue = 0;
        private void ReadWork()
        {
            try
            {


                if (IsSimulate)
                {
                    while (isContinue)
                    {
                        simuvalue++;
                        if (simuvalue > 200)
                            simuvalue = 0;
                        Thread.Sleep(500);
                        this.RaiseMessage(simuvalue.ToString());
                    }
                }
                if (IsSimulate)
                    return;
                if (com == null)
                {
                    MessageBox.Show("com is null");
                    return;
                }
                if (!com.IsOpen)
                    com.Open();
                com.DataReceived -= Com_DataReceived;
                com.DataReceived += Com_DataReceived;
                while (isContinue)
                {
                    try
                    {
                        if (!com.IsOpen)
                            com.Open();
                        //MessageBox.Show("try to send");
                        if (DevTyp == "XM05B3")
                        {
                            SndXM05B3Msg();
                        }
                        Thread.Sleep(500);
                    }
                    catch (Exception ex)
                    {
                        if (!(ex is ThreadAbortException))
                        {
                            isContinue = false;
                            MessageBox.Show(ex.Message, "出错了", MessageBoxButton.OK, MessageBoxImage.Error);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Tracer.Error(ex.StackTrace, ex);
            }
        }

        public void GetYHMsg(string name, byte[] data, int length)
        {
            string vint = "0";
            //将接收到的消息数组里真实消息转成字符串  
            if (length == 0)
                return;
            string strMsg = "";
            string value = "0";
            int idx = -1;
            strMsg = Encoding.ASCII.GetString(data, 0, length);
            string[] values = strMsg.Split(new char[] { '+' });
            foreach (string v in values)
            {
                if (v == "")
                    continue;
                if (vint == v)
                    continue;
                vint = v;
                idx = v.IndexOf("g");

                if (idx > 0)
                {
                    value = v.Substring(0, idx);
                }
                else
                {
                    idx = v.IndexOf("kg");
                    if (idx > 0)
                    {
                        value = v.Substring(0, idx);
                    }
                }
                if (idx < 0)
                    continue;
                VU = value;
                this.RaiseMessage(VU);
                //this.Dispatcher.Invoke(new SetFunctionDelegate(SetFunction), value);
            }
        }
        public void GetHTMsg(string name, byte[] data, int length)
        {

            string vint = "0";
            //将接收到的消息数组里真实消息转成字符串  
            //wn00000.00kg
            if (length == 0)
                return;
            string strMsg = "";
            string value = "0";
            int idx = -1;
            strMsg = Encoding.ASCII.GetString(data, 0, length);
            string[] values = strMsg.Split(new char[] { 'w', 'n' });
            foreach (string v in values)
            {
                if (v == "")
                    continue;
                if (vint == v)
                    continue;
                vint = v;
                idx = v.IndexOf("kg");
                if (idx > 0)
                {
                    value = v.Substring(0, idx);
                }
                else
                {
                    idx = v.IndexOf("g");
                    if (idx > 0)
                    {
                        value = v.Substring(0, idx);
                    }
                }
                if (idx < 3)
                    continue;
                if (value.Contains("-"))
                    continue;
                VU = value;
                this.RaiseMessage(VU);
                //this.Dispatcher.Invoke(new SetFunctionDelegate(SetFunction), value);
            }
        }
        public void GetCDMsg(string name, byte[] data, int length)
        {
            string value = "0";
            byte[] body = new byte[3];
            int c = 0;
            //将接收到的消息数组里真实消息转成字符串  
            if (length == 0)
                return;
            string strMsg = "";
            strMsg = Encoding.ASCII.GetString(data, 0, length);
            string[] values = strMsg.Split(new char[] { 'M', 'Y' });
            foreach (string v in values)
            {
                if (v == "")
                    continue;
                if (value == v)
                    continue;
                value = v;
                VU = value;
                this.RaiseMessage(VU);
                //this.Dispatcher.Invoke(new SetFunctionDelegate(SetFunction), vint);
            }
        }

        public void GetXM05B3Msg(string name, byte[] data, int length)
        {
            string value = "0";
            byte[] body = new byte[3];
            int c = 0;
            //将接收到的消息数组里真实消息转成字符串  
            if (length == 0)
                return;
            if (length < 12)
                return;
            int lg = 3;
            body = new byte[lg];
            c = 0;
            for (int i = 5; i < 5 + lg; i++)
            {
                body[c] = data[i];
                c++;
            }
            value = ((body[0] * 16 * 16 * 16 * 16 + body[1] * 16 * 16 + body[2]) * 0.01).ToString();
            VU = value;
            this.RaiseMessage(VU);
            Helpers.LogHelper.info("value is retrived");
            /*Thread.Sleep(300);
            SndXM05B3Msg();*/
            //this.Dispatcher.Invoke(new SetFunctionDelegate(SetFunction), vint);
        }
        public void SndXM05B3Msg()
        {
            if (com.IsOpen)
            {
                var cmd = "55AA02000001";

                Byte[] chrdata = new Byte[100];
                cmd = cmd.ToUpper();
                cmd = cmd.Replace(" ", "");
                var iLen = cmd.Length;
                iLen = iLen / 2;
                int i = 0;
                for (i = 0; i < iLen; i++)
                {
                    chrdata[i] = (Byte)chartohex(cmd[2 * i], cmd[2 * i + 1]);
                }

                com.DiscardOutBuffer();
                com.DiscardInBuffer();
                com.Write(chrdata, 0, i);
            }
        }
        public int chartohex(char chr1, char chr2)
        {
            int cTemp1, cTemp2;
            if (chr1 > '9' && chr1 <= 'F')
                cTemp1 = chr1 - 'A' + 10;
            else if (chr1 >= '0' && chr1 <= '9')
                cTemp1 = chr1 - '0';
            else
                cTemp1 = 0;

            if (chr2 > '9' && chr2 <= 'F')
                cTemp2 = chr2 - 'A' + 10;
            else if (chr2 >= '0' && chr2 <= '9')
                cTemp2 = chr2 - '0';
            else
                cTemp2 = 0;
            cTemp2 += cTemp1 * 0x10;
            return cTemp2;
        }
        public void GetXK31Msg(string name, byte[] data, int length)
        {
            string value = "0";
            byte[] body = new byte[3];
            int c = 0;
            //将接收到的消息数组里真实消息转成字符串  
            if (length == 0)
                return;
            if (length < 6)
                return;
            int lg = 3;
            body = new byte[lg];
            c = 2;
            for (int i = 1; i < 1 + lg; i++)
            {
                body[c] = data[i];
                c--;
            }
            value = ((body[0] * 100 + body[1] + body[2]) * 0.01).ToString();
            VU = value;
            this.RaiseMessage(VU);
            //this.Dispatcher.Invoke(new SetFunctionDelegate(SetFunction), vint);
        }
    }
}
